package com.sbsj.utils;

import com.sbsj.constants.Constant;
import com.sbsj.error.CustomException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.Set;

@Component
public class RedisUtil {

  public static Logger logger = LoggerFactory.getLogger(RedisUtil.class);

  private final JedisPool jedisPool;

  public RedisUtil(JedisPool jedisPool) {
    this.jedisPool = jedisPool;
  }

  /**
   * 获取Jedis实例
   */
  public synchronized Jedis getJedis() {
    try {
      if (jedisPool != null) {
        return jedisPool.getResource();
      } else {
        return null;
      }
    } catch (Exception e) {
      throw new CustomException("获取Redis资源异常:" + e.getMessage());
    }
  }

  /**
   * 释放Jedis资源
   */
  public void closePool() {
    try {
      jedisPool.close();
    } catch (Exception e) {
      throw new CustomException("释放Redis资源异常:" + e.getMessage());
    }
  }

  /**
   * 获取redis键值-object
   */
  public Object getObject(String key) {
    try (Jedis jedis = jedisPool.getResource()) {
      byte[] bytes = jedis.get(key.getBytes());
      if (StringUtil.isNotNull(bytes)) {
        return SerializableUtil.unserializable(bytes);
      }
    } catch (Exception e) {
      throw new CustomException("获取Redis键值getObject方法异常:key=" + key + " cause=" + e.getMessage());
    }
    return null;
  }

  /**
   * 设置redis键值-object
   */
  public String setObject(String key, Object value) {
    try (Jedis jedis = jedisPool.getResource()) {
      return jedis.set(key.getBytes(), SerializableUtil.serializable(value));
    } catch (Exception e) {
      throw new CustomException("设置Redis键值setObject方法异常:key=" + key + " value=" + value + " cause=" + e.getMessage());
    }
  }

  /**
   * 设置redis键值-object-expiretime
   */
  public String setObject(String key, Object value, int expiretime) {
    String result;
    try (Jedis jedis = jedisPool.getResource()) {
      result = jedis.set(key.getBytes(), SerializableUtil.serializable(value));
      if (Constant.OK.equals(result)) {
        jedis.expire(key.getBytes(), expiretime);
      }
      return result;
    } catch (Exception e) {
      throw new CustomException("设置Redis键值setObject方法异常:key=" + key + " value=" + value + " cause=" + e.getMessage());
    }
  }

  /**
   * 获取redis键值-Json
   */
  public String getJson(String key) {
    try (Jedis jedis = jedisPool.getResource()) {
      return jedis.get(key);
    } catch (Exception e) {
      throw new CustomException("获取Redis键值getJson方法异常:key=" + key + " cause=" + e.getMessage());
    }
  }

  /**
   * 设置redis键值-Json
   */
  public String setJson(String key, String value) {
    try (Jedis jedis = jedisPool.getResource()) {
      return jedis.set(key, value);
    } catch (Exception e) {
      throw new CustomException("设置Redis键值setJson方法异常:key=" + key + " value=" + value + " cause=" + e.getMessage());
    }
  }

  /**
   * 设置redis键值-Json-expiretime
   */
  public String setJson(String key, String value, int expiretime) {
    String result;
    try (Jedis jedis = jedisPool.getResource()) {
      result = jedis.set(key, value);
      if (Constant.OK.equals(result)) {
        jedis.expire(key, expiretime);
      }
      return result;
    } catch (Exception e) {
      throw new CustomException("设置Redis键值setJson方法异常:key=" + key + " value=" + value + " cause=" + e.getMessage());
    }
  }

  /**
   * 删除key
   */
  public Long delKey(String key) {
    try (Jedis jedis = jedisPool.getResource()) {
      return jedis.del(key.getBytes());
    } catch (Exception e) {
      throw new CustomException("删除Redis的键delKey方法异常:key=" + key + " cause=" + e.getMessage());
    }
  }

  /**
   * key是否存在
   */
  public Boolean exists(String key) {
    try (Jedis jedis = jedisPool.getResource()) {
      return jedis.exists(key.getBytes());
    } catch (Exception e) {
      throw new CustomException("查询Redis的键是否存在exists方法异常:key=" + key + " cause=" + e.getMessage());
    }
  }

  /**
   * 模糊查询获取key集合(keys的速度非常快，但在一个大的数据库中使用它仍然可能造成性能问题，生产不推荐使用)
   */
  public Set<String> keysS(String key) {
    try (Jedis jedis = jedisPool.getResource()) {
      return jedis.keys(key);
    } catch (Exception e) {
      throw new CustomException("模糊查询Redis的键集合keysS方法异常:key=" + key + " cause=" + e.getMessage());
    }
  }

  /**
   * 模糊查询获取key集合(keys的速度非常快，但在一个大的数据库中使用它仍然可能造成性能问题，生产不推荐使用)
   */
  public Set<byte[]> keysB(String key) {
    try (Jedis jedis = jedisPool.getResource()) {
      return jedis.keys(key.getBytes());
    } catch (Exception e) {
      throw new CustomException("模糊查询Redis的键集合keysB方法异常:key=" + key + " cause=" + e.getMessage());
    }
  }

  /**
   * 获取过期剩余时间
   */
  public Long ttl(String key) {
    Long result = -2L;
    try (Jedis jedis = jedisPool.getResource()) {
      result = jedis.ttl(key);
      return result;
    } catch (Exception e) {
      throw new CustomException("获取Redis键过期剩余时间ttl方法异常:key=" + key + " cause=" + e.getMessage());
    }
  }

}
